home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 476-500 / disk_500 / wiconify / wiconsetter.lzh / wIconSetter / Source / wIconFileIO.c < prev    next >
C/C++ Source or Header  |  1991-04-19  |  13KB  |  559 lines

  1. /*
  2.  *  WICONSETTER     A companion utility to wIconify.  wIconSetter allows
  3.  *                  you to specify custom icons for windows ans screens
  4.  *                  that normally use the default icons.
  5.  *
  6.  *  wIconFileIO.c   Handles low-level file activity.
  7.  *
  8.  *  Copyright 1990 by Davide P. Cervone, all rights reserved.
  9.  *  You may use this code, provided this copyright notice is kept intact.
  10.  */
  11.  
  12. #include <exec/types.h>
  13. #include <stdio.h>
  14. #include "wIconFile.h"
  15.  
  16. FILE *InFile;                   /* Main file pointer */
  17. int EndOfFile;                  /* TRUE if at end-of-file */
  18.  
  19. static int LineCount;           /* Number of lines read */
  20. static char Line[MAXLINE+2];    /* Line buffer */
  21. static short LinePos;           /* current position in line */
  22. static short WrdStart,WrdEnd;   /* Where the current word starts and ends */
  23.  
  24. char NextChar;                  /* the next character of the file */
  25. char Word[MAXLINE+1];           /* the word buffer */
  26.  
  27. static FILE *OldFile;           /* Saved file for DEFAULT_ICON command */
  28. static int OldLineCount;        /* Saved line count for old file */
  29.  
  30.  
  31. #define INVERSE     "\033[32;41m"
  32. #define NORMAL      "\033[m"
  33. #define COLORED     "\033[32;40m"
  34.  
  35.  
  36. /*
  37.  *  ShowError()
  38.  *
  39.  *  If the word starts and ends at the same character, move ahead so something
  40.  *    will be displayed.
  41.  *  Get the first character of the word, and end the line there.
  42.  *  Set the text color and print the first part of the line.
  43.  *  Put back the first character of the word, and save the last one.
  44.  *  Print the word in inverted lettering and go back to colored letters.
  45.  *  Put back the last letter of the word and print the rest of the line.
  46.  *  Go back to normal lettering and print the error message with a line number.
  47.  *  If the icon file is open, indicate that.
  48.  */
  49.  
  50. void ShowError(s,x1,x2,x3)
  51. char *s,*x1,*x2,*x3;
  52. {
  53.    char c;
  54.    
  55.    if (WrdStart == WrdEnd) WrdEnd++;
  56.    c = Line[WrdStart]; Line[WrdStart] = 0;
  57.    printf(COLORED);
  58.    printf("%s",Line);
  59.    Line[WrdStart] = c; c = Line[WrdEnd]; Line[WrdEnd] = 0;
  60.    printf(INVERSE); 
  61.    if (EndOfFile || Line[WrdStart] < ' ') printf(" ");
  62.       else printf("%s",&Line[WrdStart]);
  63.    printf(COLORED);
  64.    Line[WrdEnd] = c; if (c) printf("%s",&Line[WrdEnd]); else printf("\n");
  65.    printf(NORMAL);
  66.    printf(s,x1,x2,x3);
  67.    printf(" at line %d",LineCount);
  68.    if (OldFile) printf(" of Icon File");
  69.    printf("\n");
  70. }
  71.  
  72.  
  73. /*
  74.  *  Expected()
  75.  *
  76.  *  If we are at the end of file, indicate this.
  77.  *  If the word is a single character (or no characters)
  78.  *    If the character is printable, use it,
  79.  *    Otherwise, convert it to a word it control character notation.
  80.  *  Print the message saying what was seen and what was expected.
  81.  */
  82.  
  83. void Expected(s)
  84. char *s;
  85. {
  86.    char *Seen = &Word[0];
  87.    char c = Line[WrdStart];
  88.  
  89.    if (EndOfFile) Seen = "End-of-File"; else
  90.    if (WrdEnd < WrdStart+2)
  91.    {
  92.       if ((c >= ' ' && c < 0x7F) || c > 0xA0) Seen = " ", Seen[0] = c;
  93.       else
  94.       {
  95.          switch(c)
  96.          {
  97.             case '\n':
  98.                Seen = "End-of-Line";
  99.                break;
  100.  
  101.             case ' ':
  102.                Seen = "Space";
  103.                break;
  104.  
  105.             case '\t':
  106.                Seen = "TAB";
  107.                break;
  108.  
  109.             case '\033':
  110.                Seen = "ESC";
  111.                break;
  112.  
  113.             case '\0':
  114.                Seen = "NULL";
  115.                break;
  116.  
  117.             case 0x7F:
  118.                Seen = "DEL";
  119.                break;
  120.  
  121.             default:
  122.                Seen = "^ ";
  123.                Seen[1] = (c & 0x1F) + '@';
  124.                break;
  125.          }
  126.       }
  127.    }
  128.    ShowError("'%s' seen where %s was expected",Seen,s);
  129. }
  130.  
  131.  
  132. /*
  133.  *  GetNextLine()
  134.  *
  135.  *  If we can read a line from the file,
  136.  *    Mark the end of line (in case the maximum of the buffer was used)
  137.  *    Clear the position markers, and count the line.
  138.  *    Get the next character on the line.
  139.  *  Otherwise,
  140.  *    Clear the line and set the positions to the end of the line.
  141.  *    Mark the end of file (any error is treated as EOF).
  142.  */
  143.  
  144. static void GetNextLine()
  145. {
  146.    if (fgets(Line,MAXLINE,InFile))
  147.    {
  148.       Line[MAXLINE] = '\n';
  149.       Line[MAXLINE+1] = 0;
  150.       LinePos = WrdStart = WrdEnd = 0;
  151.       LineCount++;
  152.       NextChar = Line[LinePos];
  153.    } else {
  154.       NextChar = '\n'; LinePos = WrdStart = WrdEnd = MAXLINE;
  155.       EndOfFile = TRUE;
  156.    }
  157. }
  158.  
  159.  
  160. /*
  161.  *  GetNextChar()
  162.  *
  163.  *  Get the next character on the line and increment the position.
  164.  *  Set the word positions to the current position.
  165.  */
  166.  
  167. void GetNextChar()
  168. {
  169.    NextChar = Line[++LinePos];
  170.    WrdStart = WrdEnd = LinePos;
  171. }
  172.  
  173.  
  174. /*
  175.  *  SkipComments()
  176.  *
  177.  *  While we are at the beginning of a comment (indicated by '/*')
  178.  *    Move past the comment characters and increment the comment counter
  179.  *    Get the next character.
  180.  *    While we are still within a coment,
  181.  *      and until we reach a comment terminator or end-of-file,
  182.  *        If we are at the end of a line, read the next line,
  183.  *        If we are at the beginning of a nested comment, 
  184.  *          Increment the nexted count and move past the comment characters.
  185.  *        Otherwise, go on to the next character.
  186.  *      If we are at the end of the file, show an error (unbalanced comments).
  187.  *      Otherwise, skip the end-comment characters.
  188.  *      Decrement the comment nesting count.
  189.  *  If the next character is the rest-of-line comment character,
  190.  *    or if we are at the end of the file, move to the end of the line.
  191.  */
  192.  
  193. void SkipComments()
  194. {
  195.    int Nested = 0;
  196.  
  197.    while (NextChar == '/' && Line[LinePos+1] == '*')
  198.    {
  199.       LinePos += 2; Nested++;
  200.       NextChar = Line[LinePos++];
  201.       while (Nested)
  202.       {
  203.          while ((NextChar != '*' || Line[LinePos] != '/') && !EndOfFile)
  204.          {
  205.             if (NextChar == '\n' || NextChar == '\0') GetNextLine(); else
  206.             if (NextChar == '/' && Line[LinePos] == '*')
  207.                Nested++, NextChar = Line[++LinePos];
  208.             else NextChar = Line[LinePos++];
  209.          }
  210.          if (EndOfFile)
  211.          {
  212.             WrdStart = WrdEnd = MAXLINE;
  213.             Expected("End-of-Comment");
  214.          } else NextChar = Line[++LinePos];
  215.          Nested--;
  216.       }
  217.    }
  218.    if (EndOfFile || NextChar == ';') NextChar = Line[LinePos=MAXLINE];
  219. }
  220.  
  221.  
  222. /*
  223.  *  SkipSpaces()
  224.  *
  225.  *  First skip any comments.
  226.  *  While the next character is white-space,
  227.  *    Skip characters until it is not white space,
  228.  *    Then skip comments and do it again.
  229.  */
  230.  
  231. void SkipSpaces()
  232. {
  233.    SkipComments();
  234.    while (NextChar == ' ' || NextChar == '\t')
  235.    {
  236.       do NextChar = Line[++LinePos];
  237.          while (NextChar == ' ' || NextChar == '\t');
  238.       SkipComments();
  239.    }
  240. }
  241.  
  242.  
  243. /*
  244.  *  ReadNextLine()
  245.  *
  246.  *  While there is more in the file, and the current line is blank
  247.  *    Get the next line of the file and skip any comments.
  248.  *    Do this until there is actually some real data to look at.
  249.  *  Set the word positions to the current location.
  250.  */
  251.  
  252. void ReadNextLine()
  253. {
  254.    while (!EndOfFile && (NextChar == 0 || NextChar == '\n'))
  255.    {
  256.       GetNextLine();
  257.       SkipSpaces();
  258.    }
  259.    WrdStart = WrdEnd = LinePos;
  260. }
  261.  
  262.  
  263. /*
  264.  *  SkipChar()
  265.  *
  266.  *  If we are at the end of the line, read the next one,
  267.  *  Otherwise, move to the next non-blank character.
  268.  */
  269.  
  270. void SkipChar()
  271. {
  272.    if (NextChar == '\n') ReadNextLine();
  273.    else NextChar = Line[++LinePos], SkipSpaces();
  274. }
  275.  
  276.  
  277. /*
  278.  *  SkipLine()
  279.  *
  280.  *  No matter where we are on the current line, go on to the next line
  281.  *  and skip spaces.  Mark the current word positions.
  282.  */
  283.  
  284. void SkipLine()
  285. {
  286.    GetNextLine(); SkipSpaces();
  287.    WrdStart = WrdEnd = LinePos;
  288. }
  289.  
  290.  
  291. /*
  292.  *  ReadNextChar()
  293.  *
  294.  *  Get the next character and mark the beginning of a word.
  295.  *  Skip any spaces after the current character.
  296.  */
  297.  
  298. void ReadNextChar()
  299. {
  300.    NextChar = Line[++LinePos];
  301.    WrdStart = WrdEnd = LinePos;
  302.    SkipSpaces();
  303. }
  304.  
  305.  
  306. /*
  307.  *  ReadAWord()
  308.  *
  309.  *  Begin the word at the current location.
  310.  *  While the next character is a letter (or a number if they are allowed)
  311.  *    Add it to the word buffer and go to the next character
  312.  *  If the word has at least one character, mark the end of the word,
  313.  *  Otherwise, the word is a single special character.
  314.  *  Mark the end of the word in the line buffer and skip trailing spaces.
  315.  */
  316.  
  317. void ReadAWord(Numbers)
  318. int Numbers;
  319. {
  320.    short i=0;
  321.    
  322.    WrdStart = LinePos;
  323.    while ((NextChar >= 'A' && NextChar <= 'Z') ||
  324.           (NextChar >= 'a' && NextChar <= 'z') ||
  325.           (NextChar >= '0' && NextChar <= '9' && Numbers) ||
  326.            NextChar == '_')
  327.    {
  328.       Word[i++] = NextChar;
  329.       NextChar = Line[++LinePos];
  330.    }
  331.    if (i)
  332.    {
  333.       Word[i] = 0;
  334.    } else {
  335.       Word[0] = NextChar; Word[1] = 0;
  336.       NextChar = Line[++LinePos];
  337.    }
  338.    WrdEnd = LinePos;
  339.    SkipSpaces();
  340. }
  341.  
  342.  
  343. /*
  344.  *  ReadNextWord()
  345.  *
  346.  *  Read a word without allowing numbers as part of the word.
  347.  */
  348.  
  349. void ReadNextWord()
  350. {
  351.    ReadAWord(FALSE);
  352. }
  353.  
  354.  
  355. /*
  356.  *  ReadExtendedWord()
  357.  *
  358.  *  Read a word and allow numbers as part of the word.
  359.  */
  360.  
  361. void ReadExtendedWord()
  362. {
  363.    ReadAWord(TRUE);
  364. }
  365.  
  366.  
  367. /*
  368.  *  ReadNextInteger()
  369.  *
  370.  *  Get the first digit of the number.
  371.  *  If it is a minus sign, add it to the number and move on.
  372.  *  While the next character is a digit, add it to the number and move on.
  373.  *  Mark the end of the word, and skip blanks.
  374.  */
  375.  
  376. void ReadNextInteger()
  377. {
  378.    short i=0;
  379.    
  380.    NextChar = Line[LinePos=WrdStart];
  381.    if (NextChar == '-')
  382.    {
  383.       Word[i++] = NextChar;
  384.       NextChar = Line[++LinePos];
  385.    }
  386.    while (NextChar >= '0' && NextChar <= '9')
  387.    {
  388.       Word[i++] = NextChar;
  389.       NextChar = Line[++LinePos];
  390.    }
  391.    Word[i] = 0;
  392.    WrdEnd = LinePos;
  393.    SkipSpaces();
  394. }
  395.  
  396.  
  397. /*
  398.  *  ReadFullLine()
  399.  *
  400.  *  Get the first letter of the word.
  401.  *  If the first character is a quote, flag it and move past it.
  402.  *  While we are not at the end of the line (or at an end quote)
  403.  *    Add the character into the word buffer and move on.
  404.  *    If we are looking for a close quote
  405.  *      and the next character is a quoted quote,
  406.  *        add a single quote into the buffer and skip over the quotes.
  407.  *  Mark the end of the word (ie, line).
  408.  *  If we were looking for quotes, then
  409.  *     If we didn't find a closing quote, show an error, otherwise skip
  410.  *       over the close-quote.
  411.  *     Skip blanks after the string.
  412.  *  Otherwise, strip off trailing blanks from the string.
  413.  */
  414.  
  415. void ReadFullLine()
  416. {
  417.    short i = 0;
  418.    int Quoted = FALSE;
  419.  
  420.    NextChar = Line[LinePos=WrdStart];
  421.    if (NextChar == '\'')
  422.    {
  423.       Quoted = TRUE;
  424.       NextChar = Line[WrdStart=++LinePos];
  425.    }
  426.    while (NextChar != '\n' && (NextChar != '\'' || Quoted == FALSE))
  427.    {
  428.       Word[i++] = NextChar;
  429.       NextChar = Line[++LinePos];
  430.       if (Quoted)
  431.       {
  432.          if (NextChar == '\'' && Line[LinePos+1] == '\'')
  433.          {
  434.              Word[i++] = NextChar;
  435.              LinePos += 2;
  436.              NextChar = Line[LinePos];
  437.          }
  438.       }
  439.    }
  440.    WrdEnd = LinePos;
  441.    Word[i--] = 0;
  442.    if (Quoted)
  443.    {
  444.       if (NextChar == '\n') ShowError("Quoted string not terminated");
  445.          else NextChar = Line[++LinePos];
  446.       SkipSpaces();
  447.    } else {
  448.       while (i >= 0 && Word[i] == ' ') Word[i--] = 0;
  449.    }
  450. }
  451.  
  452.  
  453. /*
  454.  *  Reread()
  455.  *
  456.  *  Go back to be beginning of the word and start reading again.
  457.  */
  458.  
  459. void Reread()
  460. {
  461.    LinePos = WrdStart;
  462.    NextChar = Line[LinePos];
  463. }
  464.  
  465.  
  466. /*
  467.  *  WordToUpper()
  468.  *
  469.  *  Look through the word buffer and convert lower case letters to uppper
  470.  *  case ones.
  471.  */
  472.  
  473. void WordToUpper()
  474. {
  475.    char *s = &Word[0];
  476.    
  477.    while (*s)
  478.    {
  479.       if (*s >= 'a' && *s <= 'z') *s = *s - 'a' + 'A';
  480.       s++;
  481.    }
  482. }
  483.  
  484.  
  485. /*
  486.  *  OpenFile()
  487.  *
  488.  *  Attempt to open the specified file.
  489.  *  If successful,
  490.  *    Set the error status and line counters and read the first line
  491.  *  Return TRUE if file openned OK.
  492.  */
  493.  
  494. int OpenFile(Name)
  495. char *Name;
  496. {
  497.    int status = FALSE;
  498.    
  499.    InFile = fopen(Name,"r");
  500.    if (InFile)
  501.    {
  502.       EndOfFile = FALSE; LineCount = 0;
  503.       ReadNextLine();
  504.       status = TRUE;
  505.    }
  506.    return(status);
  507. }
  508.  
  509.  
  510. /*
  511.  *  CloseFile()
  512.  *
  513.  *  Close the file and clear the file pointer.
  514.  */
  515.  
  516. void CloseFile(theFile)
  517. FILE *theFile;
  518. {
  519.    fclose(theFile);
  520.    if (theFile == InFile) InFile = NULL;
  521. }
  522.  
  523.  
  524. /*
  525.  *  SaveOpenFile()
  526.  *
  527.  *  Save the old file pointer and old line count.
  528.  *  Clear the file pointer for future use.
  529.  */
  530.  
  531. void SaveOpenFile()
  532. {
  533.    OldFile = InFile;
  534.    OldLineCount = LineCount;
  535.    InFile = NULL;
  536. }
  537.  
  538.  
  539. /*
  540.  *  RestoreFile()
  541.  *
  542.  *  If there was an old file open,
  543.  *    Get back the old pointer and line count,
  544.  *    Reset the status, and move to the end of the line.
  545.  *    Clear the save pointer for future use.
  546.  */
  547.  
  548. void RestoreFile()
  549. {
  550.    if (OldFile)
  551.    {
  552.       InFile = OldFile;
  553.       LineCount = OldLineCount;
  554.       EndOfFile = FALSE;
  555.       NextChar = Line[LinePos=MAXLINE];
  556.       OldFile = NULL;
  557.    }
  558. }
  559.